package familytree.yu.com.sso.oauth2;

import familytree.yu.com.sso.config.UserDetailsServiceImpl;
import familytree.yu.com.sso.enums.ErrorCodeEnum;
import familytree.yu.com.sso.exception.SsoException;
import familytree.yu.com.sso.model.LoginModel;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.provider.*;
import org.springframework.security.oauth2.provider.token.AbstractTokenGranter;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @Author: yuyunbo
 * @Date: 2021/2/22 22:12
 * @Description:
 */
public class PasswordCodeTokenGranter extends AbstractTokenGranter {

    private static final String GRANT_TYPE = "password_code";
    private UserDetailsServiceImpl userDetailsService;
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    public PasswordCodeTokenGranter(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, UserDetailsServiceImpl userDetailsService, BCryptPasswordEncoder bCryptPasswordEncoder) {
        super(tokenServices, clientDetailsService, requestFactory, GRANT_TYPE);
        this.userDetailsService = userDetailsService;
        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
    }


    @Override
    protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
        Map<String, String> parameters = new LinkedHashMap<String, String>(tokenRequest.getRequestParameters());
        //客户端提交的用户名
        String username = parameters.get("username").trim();
        //客户端提交的密码
        String password = parameters.get("password").trim();

        if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
            throw new SsoException(ErrorCodeEnum.ER6);
        }

        // 从库里查用户
        LoginModel loginModel = (LoginModel) userDetailsService.loadUserByUsername(username);

        //校验密码
        if (!bCryptPasswordEncoder.matches(password, loginModel.getMemberEntity().getMemberPassword())) {
            throw new SsoException(ErrorCodeEnum.ER2);
        }

        Authentication userAuth = new UsernamePasswordAuthenticationToken(loginModel, null, loginModel.getAuthorities());

        ((AbstractAuthenticationToken) userAuth).setDetails(parameters);

        OAuth2Request storedOAuth2Request = getRequestFactory().createOAuth2Request(client, tokenRequest);
        return new OAuth2Authentication(storedOAuth2Request, userAuth);
    }


}
